import rateLimit, { ipKeyGenerator } from 'express-rate-limit';
import winston from 'winston'; // 假设项目已安装winston日志库

// 创建限流专用日志器
const limiterLogger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.File({ filename: 'logs/rate-limit.log', level: 'info' }),
    new winston.transports.Console({ format: winston.format.simple() })
  ]
});

/**
 * 通用请求频率限制中间件
 * 限制同一IP在指定时间窗口内的请求次数
 * @param {number} windowMs - 时间窗口(毫秒)
 * @param {number} max - 最大请求数
 * @param {string[]} whitelist - IP白名单数组
 */
const createRateLimiter = (
  windowMs = 15 * 60 * 1000,
  max = 100,
  whitelist = []
) => {
  return rateLimit({
    windowMs: windowMs,
    max: max,
    standardHeaders: true,
    legacyHeaders: false,
    message: {
      status: 429,
      message: '请求过于频繁，请稍后再试',
      code: 'TOO_MANY_REQUESTS'
    },
    keyGenerator: (req) => {
      // 使用express-rate-limit提供的ipKeyGenerator处理IPv6地址
      return ipKeyGenerator(req);
    },
    // IP白名单功能实现
    skip: (req) => {
      // 支持CIDR格式(如'192.168.1.0/24')和具体IP
      const isWhitelisted = whitelist.some(ip => {
        if (ip.includes('/')) {
          // 简单CIDR匹配(实际生产环境建议使用ipaddr.js库)
          const [baseIp, mask] = ip.split('/');
          const reqIpParts = req.ip.split('.').map(Number);
          const baseIpParts = baseIp.split('.').map(Number);
          const maskBits = parseInt(mask, 10);
          
          // 仅支持IPv4简单CIDR匹配
          for (let i = 0; i < maskBits / 8; i++) {
            if (reqIpParts[i] !== baseIpParts[i]) return false;
          }
          return true;
        }
        return req.ip === ip;
      });
      
      if (isWhitelisted) {
        limiterLogger.info({
          type: 'WHITELIST_SKIP',
          ip: req.ip,
          path: req.path,
          method: req.method
        });
      }
      return isWhitelisted;
    },
    // 限流日志监控
    handler: (req, res, next, options) => {
      limiterLogger.warn({
        type: 'RATE_LIMITED',
        ip: req.ip,
        path: req.path,
        method: req.method,
        windowMs: options.windowMs,
        maxRequests: options.max,
        requestCount: options.max + 1 // 当前请求数
      });
      res.status(options.message.status).json(options.message);
    }
  });
};

// 常用速率限制配置(包含白名单示例)
const internalIps = ['192.168.1.0/24', '10.0.0.0/8', '172.16.0.0/12'];
 // 登录/注册接口：15分钟内最多10次请求
const authLimiter = createRateLimiter(15 * 60 * 1000, 10, internalIps);
// 普通API接口：15分钟内最多100次请求
const apiLimiter = createRateLimiter(15 * 60 * 1000, 100);
// 敏感操作接口：5分钟内最多20次请求
const strictLimiter = createRateLimiter(5 * 60 * 1000, 20, internalIps); 

export {
  createRateLimiter,
  authLimiter,
  apiLimiter,
  strictLimiter,
  limiterLogger // 导出日志器供外部使用
};